package c.x.jy.redislock;

import java.util.Random;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

import c.x.jy.admin.redisLock.RedisLockTool;
import c.x.jy.service.redis.RedisUtils;
 
@SuppressWarnings("all")
@Component
public class DistributedLock1 {
	@Autowired
	private RedisUtils JedisUtil;
	@Autowired
	private RedisLockTool redisLockTool;
	@Autowired
	private ValueOperations valueOperations;
	@Autowired
	private RedisTemplate<String, Object> redisTemplate;

	DistributedLock1(String lockKey) {
		this.lockKey = lockKey;

	}

	private String lockKey;
	private String requestId;// = UUID.randomUUID().toString().replaceAll("-",
								// "");

	/**
	 * 获取分布式请求ID
	 * 
	 * @return
	 */
	public String getRequestId() {
		requestId = UUID.randomUUID().toString().replaceAll("-", "");
		return requestId;
	}

	// AloneLock lock1 = new AloneLock();
	/**
	 * 分布式加锁
	 * 
	 * @param requestId
	 */
	public void lock(String requestId) {
		// 超时间
		Long times = 2000l + System.currentTimeMillis();
		// if(requestId!=null)

		if (!tryLock(requestId)) {

			for (;;) {
				if (tryLock(requestId)) {
					return;
				}
				Object o = MemCacheImpl.get("redislock");
				int time = (int) (o == null ? 100 : o);

				try {

					Thread.sleep(new Random().nextInt(time) + 100);

					if (times < System.currentTimeMillis()) {
						// 如果要停上就抛异常
						// throw new RuntimeException("获取锁错误！");
						if (time < 5000) {
							time += 150;
							MemCacheImpl.put("redislock", time, 1);
						}
						System.err.println(lockKey + "  取锁超时！");
					} else {
						if (time > 100) {
							time -= 150;
							MemCacheImpl.put("redislock", time, 1);
						}

					}
				} catch (InterruptedException e) {

					e.printStackTrace();
				}
			}
		}

	}

	public boolean tryLock(String requestId) {
		// Jedis jedis = JedisUtil.getResource();
		boolean r = false;

		r = redisLockTool.tryGetDistributedLock(redisTemplate, lockKey, requestId, 5000);
		// if(r)System.out.println("取锁成功！");

		return r;

	}

	/**
	 * 如果锁超时 守护线程，服务挂了线程也就停了
	 * 
	 * @param requestId
	 */
	public void watchRedis(final String requestId) {
		try {
			Thread.sleep(4800);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		new Thread(new Runnable() {
			@Override
			public void run() {
				// Jedis jedis = JedisUtil.getResource();
				// if (jedis == null) return;
				if (requestId.equals(valueOperations.get(lockKey))) {
					redisTemplate.expire(lockKey, 5,TimeUnit.SECONDS);
				
					watchRedis(requestId);
				}
			}
		}).start();

	}

	/**
	 * 解锁
	 * 
	 * @param requestId
	 */
	public void unlock(String requestId) {
		// Jedis jedis = JedisUtil.getResource();

		//if (jedis == null)
		//	return;
		try {
			if (!redisLockTool.releaseDistributedLock(redisTemplate, lockKey, requestId)) {
				System.out.println("释放失败！" + lockKey + ":" + requestId);
				// if(jedis.get(lockKey)!=null)
				// unlock(requestId2);

			}
		} catch (Throwable e) {
			// TODO: handle exception
		}  

	}

}
